#ifndef _usart_dragonball_
#define _usart_dragonball_
#include "serial_manager.h"
#include "protocol_DragonBall.h"

namespace igslib
{
    class usart_Grgn:public CMCUUart
    { 
		protected:
			char baudidx;
			static int ID;
			char setup_ctrl[10]={0};
			int LocID;
        public:

		  usart_Grgn()
		  {
		    ID++;
			LocID=ID;
			setup_ctrl[0]=1; 
		  }
          ~usart_Grgn()
		  {
			if (ID>-1)
			ID--;	  
		  }
		
		int	remapping(int value) 
		{
			switch (value)
			{
				case 300:
					return 0;
				break;
				case 1200:
					return 0;
				break;
				case 2400:
					return 0;
				break;
				case 4800:
					return 0;
				break;
				case 9600:
					return 0;
				break;			
				case 115200:
					return 8;
				break;
				default :
					return -1;
				break;			
			}	
		}	  
		
        void SetBaudRate(int value)
		{		
			int ret=remapping(value);
			if(ret<0)
			throw_igslib_exception("Baud rate setup fail");	
			br = value;            
			setup_ctrl[5]= ret;
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
            tmp->SetupUsart(LocID, setup_ctrl);
               	
		}
	

        void SetParityMode(ParityMode value)
		{			
			if(pm==pm_none)
				setup_ctrl[6]= 0;
			else if(pm==pm_odd)
				setup_ctrl[6]= 1;
			else if(pm==pm_even)
				setup_ctrl[6]= 2;
			else
				throw_igslib_exception("ParityMode setup fail");
							
			pm = value; 	
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
            tmp->SetupUsart(LocID, setup_ctrl);
		}


         void SetDataBits(DataBits value)
		{
			
			if(value==data_5bits)
				setup_ctrl[8]= 5;
			else if(value==data_6bits)
				setup_ctrl[8]= 6;
			else if(value==data_7bits)
				setup_ctrl[8]= 7;	
			else if(value==data_8bits)
				setup_ctrl[8]= 8;
			else
				throw_igslib_exception("DataBits setup fail");
			db=value;
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
            tmp->SetupUsart(LocID, setup_ctrl);		
		}
       void SetStopBits(StopBits value)
	   {
			
			if(value==stop_1bit)
				setup_ctrl[7]= 0;
			else if(value==stop_2bits)
				setup_ctrl[7]= 1 ;

			else
				throw_igslib_exception("StopBits setup fail");
			sb=value;
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
            tmp->SetupUsart(LocID, setup_ctrl);
	
	     }

		 
		void SetWorkMode(WorkMode value)
		{
			if(value==WorkMode::passing)
				setup_ctrl[1]= 0;
			else if(value==WorkMode::function)
				setup_ctrl[1]= 1 ;

			else
			 throw_igslib_exception("WorkMode setup fail");
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
            tmp->SetupUsart(LocID, setup_ctrl);
		
		}
		void SetReceiveLen(int value)
		{
			setup_ctrl[2]= value ;
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
            tmp->SetupUsart(LocID, setup_ctrl);
		
		}
		void SetReceiveTimeout(int value)
		{
			if(value>65536)
				throw_igslib_exception("ReceiveTimeout setup fail");
			setup_ctrl[3]= value ;
			setup_ctrl[4]= value/256 ;
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
            tmp->SetupUsart(LocID, setup_ctrl);
		}
		
		 void SetSlaveOperation(bool value)
		{
			if(value == true)
			 setup_ctrl[9]= 1;
			else
			 setup_ctrl[9]= 0;
			
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
            tmp->SetupUsart(LocID, setup_ctrl);
		
		}	

		int Send(char* addr,int length)
        {
                cache.clear();
                cache.assign(addr,addr+length);
				Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
				tmp->SetUsart(LocID,length,addr);	
                return length;
        }
		int Receive(char* addr,int length) 
		{ 		
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
			int len=tmp->GetUsartNV(LocID,addr);	
			return len; 
		}

		UState GetState()
		{
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
			int ret=tmp->GetUsartSat(LocID);	
			if(ret==0)
				return UState::DValid;
			else if(ret==1)
				return UState::Transferring;
			else if(ret==2)
				return UState::DInvalid;
			else if(ret==3)
				return UState::Error;
		}

		void FlushBuffer()
		{
			
			Protocol_DragonBall* tmp = (Protocol_DragonBall*)(spi);
			tmp->FlushUsart(LocID);			
		}
		 
 	
    };
	int usart_Grgn::ID = -1;
};

#endif

/*
			3288->MCU Initial						說明
			SPI_HeaderId			0x9			
			SPI_DataLength			11			   SPI Data Length
			Data[0]				cmd	"0x00"		   initial
			Data[1]				ID			
			Data[2]				Enable	1: on, 2: off		enable/disable
			Data[3]				Mode			  "0" Passing "1"Function
			Data[4]				Rxlen			  MCU端要接收的資料長度
			Data[5]				RxTimeout[0:7]	  "MCU端要接收的資料的時間base time: ms"
			Data[6]				RxTimout[8:15]			
			Data[7]				Baud Rate		   BAUDRATE_300 = 0 , 
												   BAUDRATE_1200 = 1 , 
												   BAUDRATE_2400 = 2 , 
												   BAUDRATE_4800 = 3 , 
												   BAUDRATE_9600 = 4 , 
												   BAUDRATE_19200 = 5 ,
												   BAUDRATE_38400 = 6 ,
												   BAUDRATE_57600 = 7 ,
												   BAUDRATE_115200 = 8 ,								
			Data[8]				PrityMode			"ParityMode_None=0,
													ParityMode_ODD=1,
													ParityMode_EVEN=2"
			Data[9]				StopBit					"STOPBIT_ONE=0
													STOPBIT_TWO=1"
			Data[10]			DataLength			 value : 0 ~ 8
			Data[11]			DataLength			 value : 0 ~ 8
			SPI_DataChecksum						
*/
